Skip to main content

Develop a Basic Preprocessor

Requirements

You will need to produce a Docker container that implements a specific HTTP REST interface. See the OpenAPI specification for complete details.

There are several alternatives to accomplish this:

  • Fork an existing template - Start with a project similar to your needs (language, frameworks, process, etc.)
  • Use a code generator - Create a new project with almost everything ready to run the server
  • Build from scratch - Create your project from the ground up, as long as it follows the OpenAPI specification

Select the development path that best fits your needs and expertise.

Forking a Template​

JavaScript​

📦 Repository: preprocessing-service-example

This is a simple preprocessor written in TypeScript/JavaScript.

Quick Start

You can write the business logic in src/controllers/preprocessing.ts. The template is ready with Dockerfile and even Kubernetes YAML definitions.

Key Features:

  • Pre-configured TypeScript environment
  • Docker and Kubernetes deployment files included
  • Ready-to-use project structure

Getting Started:

  1. Fork the repository
  2. Add your dependencies
  3. Write your code

Python​

📦 Repository: preprocessing-service-example-python

This is another simple preprocessor written in Python.

Quick Start

It's ready to fork and develop your own preprocessor from it. Start at preprocessor\controllers\preprocess_controller.py — the function is _apply_preprocess.

Key Features:

  • Components to access common ePI elements such as the composition
  • Built-in support for managing HtmlElementLink Extension
  • Tools to extract and manipulate HTML content
  • Embedded ePI examples for testing

Getting Started:

  1. Fork the repository
  2. Add your dependencies
  3. Write your code
  4. Test it with the embedded ePI examples

Generic Approach using OpenAPI Generator​

You can opt to use an API server generator, for example OpenAPI Generator, which will be explained in detail.

📋 Preprocessor OpenAPI Spec:

https://raw.githubusercontent.com/Gravitate-Health/preprocessing-service-example/refs/heads/main/openapi.yaml

You can create servers with stubs in any of the supported languages.

Docker Requirements

You may need to create a Dockerfile for the Preprocessor service. Remember to expose the port where the API is published.

Installation-Free Approach

Using the official Docker image avoids installing Java or OpenAPI Generator locally. You will need Docker installed.

1. Generate a server stub​

Use the dockerized generator:

docker run --rm \
-v ${PWD}:/local --user $(id -u):$(id -g) \
openapitools/openapi-generator-cli generate \
-i https://raw.githubusercontent.com/Gravitate-Health/preprocessing-service-example/refs/heads/main/openapi.yaml \
-g <language> \
-o /local/out/<language-server>

Where <language> can be:

LanguageGenerator
Java Springspring
Python Flaskpython-flask
Node/JavaScript Expressnodejs-express-server
Go Gingo-gin-server
Rust Hyper/Towerrust-server

Checkout the full list of supported languages (+ frameworks) in openapi-generator's list of SERVER Generators

2. Implement business logic​

After generation:

  • Each endpoint will have a handler stub.
  • Implement your logic inside those functions.
  • Avoid modifying generated models or interfaces (regenerate at any time).

3. Build & run Docker image​

Ensure the docker image can be built, if there isn't any Dockerfile create one for your project.

docker build -t my-service .
docker run -p 8080:8080 my-service

Python – Flask Server​

Generate

docker run --rm \
-v ${PWD}:/local --user $(id -u):$(id -g) \
openapitools/openapi-generator-cli generate \
-i https://raw.githubusercontent.com/Gravitate-Health/preprocessing-service-example/refs/heads/main/openapi.yaml \
-g python-flask \
-o /local/generated/python-flask \
--additional-properties=packageName=preprocessor

Project Structure

generated/python-flask/
├── __main__.py # Flask root
├── openapi_server
| ├── controllers/ # handlers
| ├── models/
| ├── api/
| ├── ...
├── Dockerfile
├── requirements.txt
├── ...

Implement your code in:

openapi_server/controllers/preprocess_controller.py
FHIR Helper Libraries

You may use FHIR Python Helper modules like fhir.resources (Pydantic-based models).

Dockerfile (Flask)

Generator already provides a working Dockerfile.

Troubleshooting

If there is an issue, try changing FROM python:3-alpine in the dockerfile to FROM python:3.11-alpine.


Java – Spring Boot Server​

Generate

docker run --rm \
-v ${PWD}:/local --user $(id -u):$(id -g)\
openapitools/openapi-generator-cli generate \
-i https://raw.githubusercontent.com/Gravitate-Health/preprocessing-service-example/refs/heads/main/openapi.yaml \
-g spring \
--additional-properties=java8=true \
-o /local/generated/spring

The generated project already includes Maven or Gradle support.

Project Structure (Spring)

generated/spring/
├── pom.xml
├── src/main/java/org/openapitools/api/... # handlers
├── src/main/java/org/openapitools/model/... # models
├── ...

Write your logic inside classes under:

src/main/java/org/openapitools/api/PreprocessApiController.java

You may use FHIR Helper packages like HAPI FHIR, hapi-fhir-base provides parsing and manipulation.

Example Dockerfile (Java Spring)

generated/spring/Dockerfile

FROM maven:3.9-eclipse-temurin-17 AS build
WORKDIR /workspace

# copy pom / mvnw first to leverage Docker layer cache if sources change often
COPY pom.xml ./
COPY src ./src

# build the project (skip tests for faster builds by default)
RUN mvn -B -DskipTests package

# normalize produced jar name for the next stage
RUN cp target/*.jar app.jar

FROM eclipse-temurin:17-jre AS runtime
WORKDIR /app

# copy the assembled jar from the build stage
COPY --from=build /workspace/app.jar ./app.jar

# default Spring Boot port
EXPOSE 8080

# allow passing JVM options with JAVA_OPTS
ENV JAVA_OPTS=""

ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /app/app.jar"]